# -*- Mode: Python -*- vi:si:et:sw=4:sts=4:ts=4:syntax=python

from cerbero.build.build import modify_environment
from cerbero.tools.libtool import LibtoolLibrary
from cerbero.utils import shell, messages

class Recipe(recipe.Recipe):
    name = 'openssl'
    version = '1.0.2l'
    licenses = [License.BSD_like]
    stype = SourceType.TARBALL
    url = 'ftp://ftp.openssl.org/source/{0}-{1}.tar.gz'.format(name, version)
    deps = ['zlib']
    # Parallel make fails randomly; probably races
    allow_parallel_build = False
    patches = [name + '/0001-Make-it-possible-to-only-install-libs.patch']

    files_bins = ['openssl']
    files_libs = ['libcrypto', 'libssl']
    files_devel = ['include/openssl', 'lib/pkgconfig/openssl.pc',
                   'lib/pkgconfig/libssl.pc', 'lib/pkgconfig/libcrypto.pc']

    def prepare(self):
        # map platforms
        if self.config.target_platform == Platform.IOS:
            if self.config.target_arch == Architecture.ARMv7:
                self.openssl_platform = 'BSD-generic32'
            elif self.config.target_arch == Architecture.ARMv7S:
                self.openssl_platform = 'BSD-generic32'
            elif self.config.target_arch == Architecture.X86:
                self.openssl_platform = 'BSD-generic32'
            elif self.config.target_arch == Architecture.X86_64:
                self.openssl_platform = 'BSD-generic64'
            elif self.config.target_arch == Architecture.ARM64:
                self.openssl_platform = 'BSD-generic64'
            else:
                raise NotImplementedError
        elif self.config.target_platform == Platform.ANDROID:
            if self.config.target_arch == Architecture.ARM:
                self.openssl_platform = 'android'
            elif self.config.target_arch == Architecture.ARMv7:
                self.openssl_platform = 'android-armv7'
            elif self.config.target_arch == Architecture.X86:
                self.openssl_platform = 'android-x86'
            else:
                raise NotImplementedError

            android_dev_path = os.path.join(self.config.toolchain_prefix,
                                            "platforms", "android-9",
                                            "arch-arm", "usr");
            # Set ANDROID_DEV so that the correct library search path is set
            self.make += ' ANDROID_DEV="{0}"'.format(android_dev_path)
        elif self.config.target_platform == Platform.DARWIN:
            if self.config.target_arch == Architecture.X86:
                self.openssl_platform = 'darwin-i386-cc'
            elif self.config.target_arch == Architecture.X86_64:
                self.openssl_platform = 'darwin64-x86_64-cc'
            else:
                raise NotImplementedError
        elif self.config.target_platform == Platform.LINUX:
            if self.config.target_arch == Architecture.X86:
                self.openssl_platform = 'linux-elf'
            elif self.config.target_arch == Architecture.X86_64:
                self.openssl_platform = 'linux-x86_64'
            else:
                raise NotImplementedError
        elif self.config.target_platform == Platform.WINDOWS:
            # XXX: Remove this once the build is fixed
            messages.warning("Build currently fails on Windows! Do not import "
                "into Cerbero master!")
            # Set CROSS_COMPILE so that the correct `windres` is invoked.
            # We don't do this in Configure because that messes with CC/LD/AR etc.
            if self.config.target_arch == Architecture.X86:
                self.openssl_platform = 'mingw'
                self.make += ' CROSS_COMPILE=i686-w64-mingw32-'
            elif self.config.target_arch == Architecture.X86_64:
                self.target_host_prefix = 'x86_64-w64-mingw32-'
                self.openssl_platform = 'mingw64'
                self.make += ' CROSS_COMPILE=x86_64-w64-mingw32-'
            else:
                raise NotImplementedError
        # CFLAG is no typo!
        self.make += ' LDFLAGS+="$LDFLAGS -fPIC" CFLAG+="$CFLAGS -fPIC -DOPENSSL_PIC"'
        self.make_install = 'make install_sw'

        # We probably don't need and can't use the tools on these platforms
        if self.config.target_platform == Platform.IOS or \
            self.config.target_platform == Platform.ANDROID:
            self.make += ' build_libs openssl.pc libssl.pc libcrypto.pc'
            self.make_install = 'make install_libs'

    @modify_environment
    def configure(self):
        # OpenSSL guesses the libdir incorrectly on x86_64
        config_sh = 'sh ./Configure --prefix=' + self.config.prefix + \
            ' --libdir=lib' + self.config.lib_suffix
        if self.config.target_platform == Platform.IOS:
            config_sh += ' no-shared no-dso '
        else:
            config_sh += ' shared '
        shell.call(config_sh + self.openssl_platform, self.build_dir)

    def post_install(self):
        # XXX: Don't forget to update this when the soname is bumped!
        # We don't build shared libraries on iOS as the build system
        # of openssl is broken and iOS does not support them anyway.
        if self.config.target_platform != Platform.IOS:
            libtool_la = LibtoolLibrary('ssl', 1, 0, 0, self.config.libdir,
                                        self.config.target_platform,
                                        deps=['crypto'])
            libtool_la.save()
            libtool_la = LibtoolLibrary('crypto', 1, 0, 0, self.config.libdir,
                                        self.config.target_platform)
            libtool_la.save()
